#include <iostream>
#include <sstream>
#include <jsoncpp/json/json.h>
#include <string>
#include <memory>
// Value& operator=(const Value& other);
// Value& operator[](ArrayIndex index);
// Value& operator[](int index);
/*
具体来说，Json::Value 类重载了以下赋值操作符：
对字符串类型(const char* 和 std::string)
对整型(int, long 等)
对浮点型(float, double)
对布尔型(bool)
对数组类型(通过 append 方法)
*/
bool Serialize(Json::Value &root, std::string &body)
{

    // 序列化--把stu对象内部的key——value序列化成一个字符串然后输出到一个输出流对象
    Json::StreamWriterBuilder Bst;
    // StreamWriter 是一个抽象的基类，
    // 要定义一个工厂类对象去生产(new)一个StreamWriter的子类对象
    // 使用完要释放，避免忘记释放使用指针指针管理
    std::shared_ptr<Json::StreamWriter> sw(Bst.newStreamWriter());
    std::stringstream ss;
    // 把序列化的字符串输出到字符串输出流对象中
    int ret = sw->write(root, &ss);
    if (ret != 0)
        return false;
    body = ss.str();
    return true;
}

// json字符串反序列化到Value对象中以key--value存储
bool UnSerialize(Json::Value &root, std::string &body)
{
    Json::CharReaderBuilder Cb;
    std::shared_ptr<Json::CharReader> Cr(Cb.newCharReader());
    std::string strerr;
    bool ret = Cr->parse(body.c_str(), body.c_str() + body.size() - 1, &root, &strerr);
    return ret;
}
int main()
{
    Json::Value stu,Rpc,params;
    const char *name = "ggbond";
    int age = 18;
    const char *sex = "men";
    float score[] = {99.9, 99.8, 100.1};

    // 把不同的数据类型以key-value的形式保存到stu内部
    // key--字符串类型
    stu["name"] = name;
    stu["age"] = age;
    stu["sex"] = sex;
    // 对key对应的values追加多个value
    stu["score"].append(score[0]);
    stu["score"].append(score[1]);
    stu["score"].append(score[2]);

    Json::Value fav;
    //fav["书籍"] = "三国演义";
    //fav["运动"] = "跑步";

    // 一个Value对象中的key-value的value是可以嵌套一个Value对象的
    stu["爱好"] = fav;
    Rpc["method"]="Add";
    params["nums1"]=11;
    params["nums2"]=22;

    Rpc["params"]=params;

    std::string body;
    Serialize(Rpc, body);
    std::cout << body << std::endl;

    // Json::Value r1;
    // UnSerialize(r1, body);

    // std::cout << "name: " << r1["name"].asString() << std::endl;
    // std::cout << "age: " << r1["age"].asInt() << std::endl;
    // std::cout << "sex: " << r1["sex"].asString() << std::endl;

    // int size = r1["score"].size();
    // std::cout << "socre: " << std::endl;
    // for (int i = 0; i < size; i++)
    // {
    //     std::cout << r1["score"][i].asFloat() << std::endl;
    // }
     //std::cout<<r1["爱好"]["书籍"].asString()<< std::endl;
}